# -*- encoding:utf-8 -*-

from plugins import CheckPlugin
from config import logger
from helper import CallProcess, raw2lines

'''
Network status

Only show ipv4 TCP state
  - ESTABLISHED
  - CLOSED
  - LISTEN
'''

def _parse_addr(addr):
    r_dotidx = addr.rfind('.')
    has_colon = lambda x: x.find(':') >= 0
    has_ast = lambda x: x.find('*') >= 0
    ast2zero = lambda x: has_ast(x) and '0.0.0.0' or x
    if has_colon(addr):
        addr_li = addr.split(':')
    else:
        addr_li = [addr[:r_dotidx], addr[r_dotidx+1:]]
    return [ast2zero(addr_li[0]), addr_li[1]]

class CheckTcpState(CheckPlugin):

    topic = 'tcp_state'

    def check(self):
        cmd = '/usr/bin/netstat -f inet -p tcp -na'
        logger.debug('%s check cmd: %s' % (self.topic, cmd))
        proc = CallProcess(cmd)
        proc()
        lines = raw2lines(proc.stdout, 2)
        for line in lines:
            values = [l.strip() for l in line.split()]
            self.results.append({'proto': values[0],
                                 'recv_q': values[1],
                                 'send_q': values[2],
                                 'local_addr': _parse_addr(values[3]),   # [ip, port]
                                 'foreign_addr': _parse_addr(values[4]), # [ip, port]
                                 'state': values[5]})


class CheckSocketState(CheckPlugin):
    topic = 'socket_state'

    def check(self):
        cmd = '/usr/bin/sockstat -l -4'
        logger.debug('%s check cmd: %s' % (self.topic, cmd))
        data = {}
        proc = CallProcess(cmd)
        proc()
        lines = raw2lines(proc.stdout, 1)
        for line in lines:
            values = [l.strip() for l in line.split()]
            if values[-2] == '*:*':
                continue
            port = _parse_addr(values[-2])[-1]
            if port not in data:
                data[port] = {'user': values[0],
                                   'command': values[1],
                                   'pid': [values[2]],
                                   'fd': values[3],
                                   'proto': values[4],
                                   'local_addr': _parse_addr(values[5]),
                                   'foreign_addr': _parse_addr(values[6])}
            else:
                data[port]['pid'].append(values[2])
        self.results = [data]

